/*
** Pine Tree Modeling by Neil C. Obremski                     [ Magenta's Maze ]
** 2017 Gibdon Moon Productions                   [ http://magsmaze.gibdon.com ]
**
** This is free and unencumbered software released into the public domain.
**
** Anyone is free to copy, modify, publish, use, compile, sell, or
** distribute this software, either in source code form or as a compiled
** binary, for any purpose, commercial or non-commercial, and by any
** means.
**
** In jurisdictions that recognize copyright laws, the author or authors
** of this software dedicate any and all copyright interest in the
** software to the public domain. We make this dedication for the benefit
** of the public at large and to the detriment of our heirs and
** successors. We intend this dedication to be an overt act of
** relinquishment in perpetuity of all present and future rights to this
** software under copyright law.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
** OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
** OTHER DEALINGS IN THE SOFTWARE.
**
** Tested w/ DOSBox 0.74, Microsoft C 5.10
 */
#ifndef __MAG_TREE
#define __MAG_TREE

#include "mag-3d.h"
#include "mag-map.h"
#include "mag-math.h"

void model_leaves(struct mesh*, int, int);
void model_tree(struct mesh**, struct mesh**, struct mesh**);
char tile_tree(char lowdetail);

/* initializes a leaves model (leaves and cone) */
void model_leaves(struct mesh *ptree, int w, int h)
{
	int i, degstep = 360 / 8;	/* degree step (45) */
	int deg1, deg2, deg3;
	int x1, y1, z1, x2, y2, z2, x3, y3, z3;

	reset(ptree, A_OUTLN, BLACK, CYAN);

	for (i = 0; i < 8; i++) {

		deg1 = degstep * i;
		deg2 = deg1 + (degstep >> 1);
		deg3 = deg1 + degstep;

		if (deg2 >= 360) {
			deg2 -= 360;
		}

		if (deg3 >= 360) {
			deg3 -= 360;
		}

		x1 = MUL_COS_DEG(w,deg1);
		y1 = 0;
		z1 = MUL_SIN_DEG(w,deg1);

		x2 = MUL_COS_DEG(w,deg2);
		y2 = -h;
		z2 = MUL_SIN_DEG(w,deg2);

		x3 = MUL_COS_DEG(w,deg3);
		y3 = 0;
		z3 = MUL_SIN_DEG(w,deg3);

		if (MESH_POLY_MAX == addpoly(ptree, 0,h,0, x1,y1,z1, x3,y3,z3, 0) ||
			MESH_POLY_MAX == addpoly(ptree, x1,y1,z1, x2,y2,z2, x3,y3,z3, 0)) {
			dump(ptree, FALSE);
			printf("LEAVES ERROR: Out of Vtx/Tri Memory\n");
			exit(1);
		}
	}

	normals(ptree);
}

/* compound model is actually 3 separate meshes (bottom, middle, top) */
void model_tree(struct mesh **pbot, struct mesh **pmid, struct mesh **ptop)
{
	struct mesh *bot = model('B'), *mid = model('M'), *top = model('T');

	if (!bot || !mid || !top) {
		bot = addmodel('B');
		model_leaves(bot, 60, 60);
		translate(bot, 0, -40, 0);

		mid = addmodel('L');
		model_leaves(mid, 40, 45);
		rotatey(mid, 350);

		top = addmodel('T');
		model_leaves(top, 20, 30);
		translate(top, 0, 40, 0);
	}

	*pbot = bot;
	*pmid = mid;
	*ptop = top;
}

/* intializes a tree tile using models B=bottom, L=leaves, T=tree */
char tile_tree(char lowdetail)
{
	struct mesh *bot, *mid, *top;

	model_tree(&bot, &mid, &top);

	if (lowdetail) { /* render only tree outlines in low-detail mode */
		bot->a = mid->a = top->a = A_OUTLE;
		bot->stroke = mid->stroke = top->stroke = CYAN;
		bot->fill = mid->fill = top->fill = BLACK;
	}

	return addtile(bot, mid, top, 'T', TILE_CH_EMPTY, 0);
}

#endif
